#ifndef __CONTEXT_H__
#define __CONTEXT_H__

#include <types.h>
#include <fpu.h>

#define KSTACK_SIZE	PAGE_SIZE	// PL0 stack for thread
#define USTACK_SIZE	2*PAGE_SIZE	// PL3 stack for user thread

#define USER_THREAD	0x80000000
#define KERNEL_THREAD	0x00000000

typedef struct {
    uint32_t gs;
    uint32_t fs;
    uint32_t es;
    uint32_t ds;

    uint32_t edi;
    uint32_t esi;
    uint32_t ebp;
    uint32_t esp;
    uint32_t ebx;
    uint32_t edx;
    uint32_t ecx;
    uint32_t eax;

    uint32_t user_eip;
    uint32_t user_cs;
    uint32_t user_eflags;
    uint32_t user_esp;
    uint32_t user_ss;
} userframe_t;

typedef struct {
    userframe_t *stack0;	// kernel mode stack ptr
    uint32_t *kstack;		// kernel mode stack ptr (kstack_top);
    uint32_t *ustack;		// stack ptr of user proc

    fpustate_t *fpu;
    fxsrstate_t *fxsr;
} context_t;

int context_init(context_t *ctx);
int context_setup(context_t *ctx, void *ustack, void (*entry) ());
int context_destroy(context_t *ctx);

#endif	/* __CONTEXT_H__ */
